# Dastyor

Introduction
**Dastyor** is a lightweight Python web framework designed for learning purposes. It provides a minimalistic approach to web development, allowing you to build web applications quickly and with minimal boilerplate code.
### Features
- Simple and intuitive API
- Built-in support for routing and templating
- Integration with popular libraries
## Installation
To install Dastyor, use pip:
```bash
pip install dastyor
```
## CLI Commands[optional]
### `dastyor get_samlple.`
The `get_sample` command generates a default `main.py` file with example code for custom handlers if the file does not already exist. This command is useful for quickly setting up a basic structure for a Dastyor application.
#### **Usage:**
To use the `get_sample` command, run the following command in your terminal:
```terminal
dastyor get_sample
```
#### Behavior
* **File Check:** The command checks if `main.py` already exists in the current directory.
* **File Creation:** If `main.py` does not exist, the command creates the file with predefined content.
* **Content:** The generated `main.py` file includes:
* Import statements for `DastyorApp`.
* An example route handler for the home page.
* A placeholder for adding custom code.
* A section to run the server if the script is executed as the main module.
#### **Example.**
When you run `dastyor get_sample`, it will generate a `main.py` file with the following content:
```python
from dastyor.app import DastyorApp
app = DastyorApp()
# Example for custom handler
@app.route("/", allowed_methods=['get'])
def home(request, response):
response.text = "Hey from Home page"
# Type your code here
if __name__ == '__main__':
app.runserver()
```
If `main.py` already exists in the current directory, the command will output:
```terminal
File 'main.py' already exists.
```
If `main.py` does not exist, the command will create the file and output:
```terminal
Default main.py created in <current_directory>
```
## **Getting Start**
- **CLI command:** Use this command to get sample custom handler[optional]. `dastyor get_sample`
- **Basic Usage**: Show a simple example of setting up a basic application using your framework.
- **Configuration**: Explain any configuration options available.
---
#### It's important.
> The following code should be placed at the bottom of your main handler file:
>
> ```PYTHON
> if __name__ == '__main__':
> app.runserver()
> ```
>
> use following command to run the server.
>
> ```
> python file_name.py
> ```
>
> for instance I got handler file called `main.py` then I should type `python main.py` to run the server.
---
Here's a quick example to get you started with Dastyor:
### 1. Basic Routing.
**Define simple routes using decorators:**
```python
from dastyor.app import DastyorApp
app = DastyorApp()
@app.route("/", allowed_methods=['get'])
def home(request, response):
response.text = "Hey from Home page"
@app.route("/about")
def about(request, response):
response.text = "Message from About page"
```
`/` route responds with "Hey from Home page".
`/about` route responds with "Message from About page".
### 2. **Dynamic Routing.**
Handle dynamic URL parameters with route placeholders:
```python
@app.route("/welcome/{name}")
def welcome(request, response, name):
response.text = f"Welcome {name}"
```
`/welcome/{name}` route responds with a personalized welcome message.
### 3. **Class-Based Views**
Define routes using classes for different HTTP methods:
```python
@app.route('/books')
class Books:
def get(self, request, response):
response.text = "Books Page"
def post(self, request, response):
response.text = "Endpoint to create a book"
```
`/books` route responds with "Books Page" for GET requests and "Endpoint to create a book" for POST requests.
### 4. **Adding Routes Dynamically**
Add routes to your application dynamically:
```python
def new_handler(request, response):
response.text = "From new handler"
app.add_route("/new-handler", new_handler)
```
`/new-handler` route responds with "From new handler".
### 5. **Rendering Templates**
Use templates to render HTML responses:
```python
@app.route("/template")
def template_handler(request, response):
response.html = app.template(
"home.html",
context = {
'new_title': "Best title", 'new_body': "Best body"
}
)
```
`/template` route renders `home.html` with provided context.
### 6. **Exception Handling**
Handle exceptions globally:
```python
def on_exception(request, response, exception_class):
response.text = str(exception_class)
app.add_exception_handler(on_exception)
@app.route("/exception")
def exception_throwing_handler(request, response):
raise AttributeError("Some Exception")
```
`/exception` route raises an exception, and `on_exception` handler will return the exception message.
### 7. **Middleware**
Create middleware to process requests and responses:
```python
from dastyor.middleware import Middleware
class LoggingMiddleware(Middleware):
def process_request(self, request):
print("Request is being called", request.url)
def process_response(self, request, response):
print("Response has been generated", request.url)
app.add_middleware(LoggingMiddleware)
```
`LoggingMiddleware` prints log messages for incoming requests and outgoing responses.
### 8. **JSON Responses**
Send JSON responses:
```python
@app.route("/json")
def json_response(request, response):
response.json = {"name": "Dastyor python web framework."}
```
`/json` route returns a JSON response with framework information.
### **9. Serving Static Files.**
Dastyor supports serving static files, such as CSS, JavaScript, and images, which can be referenced in your HTML templates. This is useful for including stylesheets, scripts, and other static assets in your web application.
#### Serving Static Files.
To serve static files, you need to place them in a specific directory and configure your application to serve them. By default, static files are served from the `static` directory.
#### Example Directory Structure.
Here’s an example of how your project directory might be organized:
```
my_project/
│
├── static/
│ ├── home.css
│
├── templates/
│ ├── home.html
│
├── app.py
└── manage.py
```
* `static/`: Directory containing static files like CSS, JavaScript, and images.
* `templates/`: Directory containing HTML templates.
#### Example HTML Template.
In your HTML templates, you can reference static files using the `/static/` URL prefix. For example:
```html
<!DOCTYPE html>
<html>
<head>
<title>{{ new_title }}</title>
<link rel="stylesheet" href="/static/home.css">
</head>
<body>
{{ new_body }}
</body>
</html>
```
In this example, `home.css` is a CSS file located in the `static/` directory. The `href` attribute in the `<link>` tag points to `/static/home.css`, which will serve the stylesheet to the browser.
#### Serving Static Files in Your Application.
Ensure that your application is configured to serve static files from the `static` directory. In Dastyor, static files are automatically served from the `static` directory by default. No additional configuration is required.
#### Customizing Static File Handling.
If you need to customize how static files are served or change the directory, you can adjust the configuration in your application setup. Check the documentation or configuration options available in your framework for more details.
## Product Level Testing.
Product level testing focuses on ensuring that your web application built with Dastyor performs as expected in real-world scenarios. Below are examples of how to write and organize tests for a web application using Dastyor.
### Example Tests.
#### * Basic Functionality.
Test basic routes and responses:
`test_app.py` (you may call this filename whatever you want)
```python
import pytest
from dastyor.wsgi import DastyorApp
@pytest.fixture
def app():
"""Fixture to provide a DastyorApp instance for testing."""
app = DastyorApp()
# Optionally, you can configure the app here, add routes, etc.
# For example, you can add routes or middleware specific to your tests.
return app
@pytest.fixture
def test_client(app):
"""Fixture to provide a test client session for making requests."""
return app.test_session()
def test_home_page(test_client):
response = test_client.get('http://testserver/')
assert response.status_code == 200
assert response.text == "Hey from Home page"
def test_about_page(test_client):
response = test_client.get('http://testserver/about')
assert response.status_code == 200
assert response.text == "Message from About page"
```
#### * Dynamic Routing.
Test dynamic routes with parameters:
```python
def test_welcome_page(test_client):
response = test_client.get('http://testserver/welcome/Mirolim')
assert response.status_code == 200
assert response.text == "Welcome Mirolim"
```
#### * Static Files.
Test serving static files:
```python
def test_serving_static_files(test_client):
response = test_client.get('http://testserver/static/home.css')
assert response.status_code == 200
assert "body { background-color: chocolate; }" in response.text
def test_non_existent_static_file(test_client):
response = test_client.get('http://testserver/static/nonexistent.css')
assert response.status_code == 404
```
#### * Template Rendering.
Test rendering of HTML templates:
```python
def test_template_rendering(test_client):
response = test_client.get('http://testserver/template')
assert response.status_code == 200
assert "Best title" in response.text
assert "Best body" in response.text
```
#### * Error Handling.
Test custom error handling:
```python
def test_custom_exception_handling(test_client):
response = test_client.get('http://testserver/exception')
assert response.status_code == 500
assert "Some Exception" in response.text
```
#### * Middleware.
Test middleware functionality:
```python
def test_middleware_processing(test_client):
response = test_client.get('http://testserver/home')
assert response.status_code == 200
# Check middleware side-effects or logging here
```
#### * JSON Responses.
* [ ] Test JSON response handling:
```python
def test_json_response(test_client):
response = test_client.get('http://testserver/json')
assert response.status_code == 200
assert response.headers['Content-Type'] == 'application/json'
assert response.json()['name'] == 'Dastyor python web framework.'
```
#### * Running Your Tests.
To run your tests, execute the following command in your terminal:
```terminal
pytest
```
Raw data
{
"_id": null,
"home_page": "https://github.com/mirolim-dev/dastyor",
"name": "dastyor",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9.0",
"maintainer_email": null,
"keywords": null,
"author": "Mirolimjon Turgunov",
"author_email": "mirolimcoder@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/9e/a8/196a34a8d1ef51a32d384678234c6e890f448bdb4259217ce957d7305a9c/dastyor-0.1.9.tar.gz",
"platform": null,
"description": "\r\n# Dastyor\r\n\r\n\r\n\r\nIntroduction\r\n\r\n**Dastyor** is a lightweight Python web framework designed for learning purposes. It provides a minimalistic approach to web development, allowing you to build web applications quickly and with minimal boilerplate code.\r\n\r\n### Features\r\n\r\n- Simple and intuitive API\r\n- Built-in support for routing and templating\r\n- Integration with popular libraries\r\n\r\n## Installation\r\n\r\nTo install Dastyor, use pip:\r\n\r\n```bash\r\npip install dastyor\r\n```\r\n\r\n## CLI Commands[optional]\r\n\r\n### `dastyor get_samlple.`\r\n\r\nThe `get_sample` command generates a default `main.py` file with example code for custom handlers if the file does not already exist. This command is useful for quickly setting up a basic structure for a Dastyor application.\r\n\r\n#### **Usage:**\r\n\r\nTo use the `get_sample` command, run the following command in your terminal:\r\n\r\n```terminal\r\ndastyor get_sample\r\n```\r\n\r\n#### Behavior\r\n\r\n* **File Check:** The command checks if `main.py` already exists in the current directory.\r\n* **File Creation:** If `main.py` does not exist, the command creates the file with predefined content.\r\n* **Content:** The generated `main.py` file includes:\r\n * Import statements for `DastyorApp`.\r\n * An example route handler for the home page.\r\n * A placeholder for adding custom code.\r\n * A section to run the server if the script is executed as the main module.\r\n\r\n#### **Example.**\r\n\r\nWhen you run `dastyor get_sample`, it will generate a `main.py` file with the following content:\r\n\r\n```python\r\nfrom dastyor.app import DastyorApp\r\n\r\napp = DastyorApp()\r\n\r\n# Example for custom handler\r\n@app.route(\"/\", allowed_methods=['get'])\r\ndef home(request, response):\r\n response.text = \"Hey from Home page\"\r\n\r\n# Type your code here\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nif __name__ == '__main__':\r\n app.runserver()\r\n\r\n```\r\n\r\nIf `main.py` already exists in the current directory, the command will output:\r\n\r\n```terminal\r\nFile 'main.py' already exists.\r\n```\r\n\r\nIf `main.py` does not exist, the command will create the file and output:\r\n\r\n```terminal\r\nDefault main.py created in <current_directory>\r\n```\r\n\r\n## **Getting Start**\r\n\r\n- **CLI command:** Use this command to get sample custom handler[optional]. `dastyor get_sample`\r\n- **Basic Usage**: Show a simple example of setting up a basic application using your framework.\r\n- **Configuration**: Explain any configuration options available.\r\n\r\n---\r\n\r\n#### It's important.\r\n\r\n> The following code should be placed at the bottom of your main handler file:\r\n>\r\n> ```PYTHON\r\n> if __name__ == '__main__':\r\n> app.runserver()\r\n> ```\r\n>\r\n> use following command to run the server.\r\n>\r\n> ```\r\n> python file_name.py\r\n> ```\r\n>\r\n> for instance I got handler file called `main.py` then I should type `python main.py` to run the server.\r\n\r\n---\r\n\r\n\r\n\r\nHere's a quick example to get you started with Dastyor:\r\n\r\n### 1. Basic Routing.\r\n\r\n**Define simple routes using decorators:**\r\n\r\n```python\r\nfrom dastyor.app import DastyorApp\r\napp = DastyorApp()\r\n\r\n@app.route(\"/\", allowed_methods=['get'])\r\ndef home(request, response):\r\n response.text = \"Hey from Home page\"\r\n\r\n@app.route(\"/about\")\r\ndef about(request, response):\r\n response.text = \"Message from About page\"\r\n```\r\n\r\n`/` route responds with \"Hey from Home page\".\r\n\r\n`/about` route responds with \"Message from About page\".\r\n\r\n### 2. **Dynamic Routing.**\r\n\r\nHandle dynamic URL parameters with route placeholders:\r\n\r\n```python\r\n@app.route(\"/welcome/{name}\")\r\ndef welcome(request, response, name):\r\n response.text = f\"Welcome {name}\"\r\n```\r\n\r\n`/welcome/{name}` route responds with a personalized welcome message.\r\n\r\n### 3. **Class-Based Views**\r\n\r\nDefine routes using classes for different HTTP methods:\r\n\r\n```python\r\n@app.route('/books')\r\nclass Books:\r\n def get(self, request, response):\r\n response.text = \"Books Page\"\r\n\r\n def post(self, request, response):\r\n response.text = \"Endpoint to create a book\"\r\n```\r\n\r\n`/books` route responds with \"Books Page\" for GET requests and \"Endpoint to create a book\" for POST requests.\r\n\r\n### 4. **Adding Routes Dynamically**\r\n\r\nAdd routes to your application dynamically:\r\n\r\n```python\r\ndef new_handler(request, response):\r\n response.text = \"From new handler\"\r\n\r\napp.add_route(\"/new-handler\", new_handler)\r\n```\r\n\r\n`/new-handler` route responds with \"From new handler\".\r\n\r\n### 5. **Rendering Templates**\r\n\r\nUse templates to render HTML responses:\r\n\r\n```python\r\n@app.route(\"/template\")\r\ndef template_handler(request, response):\r\n response.html = app.template(\r\n \"home.html\",\r\n context = {\r\n 'new_title': \"Best title\", 'new_body': \"Best body\"\r\n }\r\n )\r\n```\r\n\r\n`/template` route renders `home.html` with provided context.\r\n\r\n### 6. **Exception Handling**\r\n\r\nHandle exceptions globally:\r\n\r\n```python\r\ndef on_exception(request, response, exception_class):\r\n response.text = str(exception_class)\r\n\r\napp.add_exception_handler(on_exception)\r\n\r\n@app.route(\"/exception\")\r\ndef exception_throwing_handler(request, response):\r\n raise AttributeError(\"Some Exception\")\r\n```\r\n\r\n`/exception` route raises an exception, and `on_exception` handler will return the exception message.\r\n\r\n### 7. **Middleware**\r\n\r\nCreate middleware to process requests and responses:\r\n\r\n```python\r\nfrom dastyor.middleware import Middleware\r\n\r\nclass LoggingMiddleware(Middleware):\r\n def process_request(self, request):\r\n print(\"Request is being called\", request.url)\r\n \r\n def process_response(self, request, response):\r\n print(\"Response has been generated\", request.url)\r\n\r\napp.add_middleware(LoggingMiddleware)\r\n```\r\n\r\n`LoggingMiddleware` prints log messages for incoming requests and outgoing responses.\r\n\r\n### 8. **JSON Responses**\r\n\r\nSend JSON responses:\r\n\r\n```python\r\n@app.route(\"/json\")\r\ndef json_response(request, response):\r\n response.json = {\"name\": \"Dastyor python web framework.\"}\r\n```\r\n\r\n`/json` route returns a JSON response with framework information.\r\n\r\n### **9. Serving Static Files.**\r\n\r\nDastyor supports serving static files, such as CSS, JavaScript, and images, which can be referenced in your HTML templates. This is useful for including stylesheets, scripts, and other static assets in your web application.\r\n\r\n#### Serving Static Files.\r\n\r\nTo serve static files, you need to place them in a specific directory and configure your application to serve them. By default, static files are served from the `static` directory.\r\n\r\n#### Example Directory Structure.\r\n\r\nHere\u2019s an example of how your project directory might be organized:\r\n\r\n```\r\nmy_project/\r\n\u2502\r\n\u251c\u2500\u2500 static/\r\n\u2502 \u251c\u2500\u2500 home.css\r\n\u2502\r\n\u251c\u2500\u2500 templates/\r\n\u2502 \u251c\u2500\u2500 home.html\r\n\u2502\r\n\u251c\u2500\u2500 app.py\r\n\u2514\u2500\u2500 manage.py\r\n\r\n```\r\n\r\n* `static/`: Directory containing static files like CSS, JavaScript, and images.\r\n* `templates/`: Directory containing HTML templates.\r\n\r\n#### Example HTML Template.\r\n\r\nIn your HTML templates, you can reference static files using the `/static/` URL prefix. For example:\r\n\r\n```html\r\n<!DOCTYPE html>\r\n<html>\r\n<head>\r\n <title>{{ new_title }}</title>\r\n <link rel=\"stylesheet\" href=\"/static/home.css\">\r\n</head>\r\n<body>\r\n {{ new_body }}\r\n</body>\r\n</html>\r\n```\r\n\r\nIn this example, `home.css` is a CSS file located in the `static/` directory. The `href` attribute in the `<link>` tag points to `/static/home.css`, which will serve the stylesheet to the browser.\r\n\r\n#### Serving Static Files in Your Application.\r\n\r\nEnsure that your application is configured to serve static files from the `static` directory. In Dastyor, static files are automatically served from the `static` directory by default. No additional configuration is required.\r\n\r\n#### Customizing Static File Handling.\r\n\r\nIf you need to customize how static files are served or change the directory, you can adjust the configuration in your application setup. Check the documentation or configuration options available in your framework for more details.\r\n\r\n## Product Level Testing.\r\n\r\nProduct level testing focuses on ensuring that your web application built with Dastyor performs as expected in real-world scenarios. Below are examples of how to write and organize tests for a web application using Dastyor.\r\n\r\n### Example Tests.\r\n\r\n#### * Basic Functionality.\r\n\r\nTest basic routes and responses:\r\n\r\n`test_app.py` (you may call this filename whatever you want)\r\n\r\n```python\r\nimport pytest\r\nfrom dastyor.wsgi import DastyorApp\r\n\r\n@pytest.fixture\r\ndef app():\r\n \"\"\"Fixture to provide a DastyorApp instance for testing.\"\"\"\r\n app = DastyorApp()\r\n \r\n # Optionally, you can configure the app here, add routes, etc.\r\n # For example, you can add routes or middleware specific to your tests.\r\n \r\n return app\r\n\r\n@pytest.fixture\r\ndef test_client(app):\r\n \"\"\"Fixture to provide a test client session for making requests.\"\"\"\r\n return app.test_session()\r\n\r\ndef test_home_page(test_client):\r\n response = test_client.get('http://testserver/')\r\n assert response.status_code == 200\r\n assert response.text == \"Hey from Home page\"\r\n\r\ndef test_about_page(test_client):\r\n response = test_client.get('http://testserver/about')\r\n assert response.status_code == 200\r\n assert response.text == \"Message from About page\"\r\n```\r\n\r\n#### * Dynamic Routing.\r\n\r\nTest dynamic routes with parameters:\r\n\r\n```python\r\ndef test_welcome_page(test_client):\r\n response = test_client.get('http://testserver/welcome/Mirolim')\r\n assert response.status_code == 200\r\n assert response.text == \"Welcome Mirolim\"\r\n\r\n```\r\n\r\n#### * Static Files.\r\n\r\nTest serving static files:\r\n\r\n```python\r\ndef test_serving_static_files(test_client):\r\n response = test_client.get('http://testserver/static/home.css')\r\n assert response.status_code == 200\r\n assert \"body { background-color: chocolate; }\" in response.text\r\n\r\ndef test_non_existent_static_file(test_client):\r\n response = test_client.get('http://testserver/static/nonexistent.css')\r\n assert response.status_code == 404\r\n```\r\n\r\n#### * Template Rendering.\r\n\r\nTest rendering of HTML templates:\r\n\r\n```python\r\ndef test_template_rendering(test_client):\r\n response = test_client.get('http://testserver/template')\r\n assert response.status_code == 200\r\n assert \"Best title\" in response.text\r\n assert \"Best body\" in response.text\r\n```\r\n\r\n#### * Error Handling.\r\n\r\nTest custom error handling:\r\n\r\n```python\r\ndef test_custom_exception_handling(test_client):\r\n response = test_client.get('http://testserver/exception')\r\n assert response.status_code == 500\r\n assert \"Some Exception\" in response.text\r\n```\r\n\r\n#### * Middleware.\r\n\r\nTest middleware functionality:\r\n\r\n```python\r\ndef test_middleware_processing(test_client):\r\n response = test_client.get('http://testserver/home')\r\n assert response.status_code == 200\r\n # Check middleware side-effects or logging here\r\n```\r\n\r\n#### * JSON Responses.\r\n\r\n* [ ] Test JSON response handling:\r\n\r\n```python\r\ndef test_json_response(test_client):\r\n response = test_client.get('http://testserver/json')\r\n assert response.status_code == 200\r\n assert response.headers['Content-Type'] == 'application/json'\r\n assert response.json()['name'] == 'Dastyor python web framework.'\r\n```\r\n\r\n#### * Running Your Tests.\r\n\r\nTo run your tests, execute the following command in your terminal:\r\n\r\n```terminal\r\npytest\r\n```\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python web framework built for learning purposes.",
"version": "0.1.9",
"project_urls": {
"Homepage": "https://github.com/mirolim-dev/dastyor"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d4f046ff62d8081c956f7e4e019c996592626029e7f59ae99df84d5b09a9b65f",
"md5": "4bda4bef5e339480c3b836cfb550c381",
"sha256": "e21c2f9f8d5a8f618e191b6d3b2fdea421df5f3af85d323713c9641f473e993b"
},
"downloads": -1,
"filename": "dastyor-0.1.9-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "4bda4bef5e339480c3b836cfb550c381",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.9.0",
"size": 9611,
"upload_time": "2024-08-05T13:34:40",
"upload_time_iso_8601": "2024-08-05T13:34:40.481103Z",
"url": "https://files.pythonhosted.org/packages/d4/f0/46ff62d8081c956f7e4e019c996592626029e7f59ae99df84d5b09a9b65f/dastyor-0.1.9-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "9ea8196a34a8d1ef51a32d384678234c6e890f448bdb4259217ce957d7305a9c",
"md5": "87adfd053e6f9f50c183262aba372d1f",
"sha256": "719b05fe0e62bf0a5b00766df1a6f6ba2907740d70cbc7bce1d49a21e14cf98b"
},
"downloads": -1,
"filename": "dastyor-0.1.9.tar.gz",
"has_sig": false,
"md5_digest": "87adfd053e6f9f50c183262aba372d1f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9.0",
"size": 12949,
"upload_time": "2024-08-05T13:34:42",
"upload_time_iso_8601": "2024-08-05T13:34:42.966855Z",
"url": "https://files.pythonhosted.org/packages/9e/a8/196a34a8d1ef51a32d384678234c6e890f448bdb4259217ce957d7305a9c/dastyor-0.1.9.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-05 13:34:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "mirolim-dev",
"github_project": "dastyor",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [],
"lcname": "dastyor"
}