{"id":22088061,"url":"https://github.com/bw9ubwo/flask-pydanql-api","last_synced_at":"2026-05-06T23:32:12.535Z","repository":{"id":192851574,"uuid":"686961181","full_name":"bw9ubwo/flask-pydanql-api","owner":"bw9ubwo","description":"Flask-PydanqlAPI: Automate Your RESTful Endpoint Creation","archived":false,"fork":false,"pushed_at":"2023-09-12T12:29:58.000Z","size":30,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-23T22:42:27.175Z","etag":null,"topics":["api","easy-to-use","flask","out-of-the-box","postgresql","pydanql","pydantic","python","rest-api"],"latest_commit_sha":null,"homepage":"https://blacktre.es","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bw9ubwo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-04T10:09:59.000Z","updated_at":"2023-09-12T14:59:37.000Z","dependencies_parsed_at":"2023-11-10T14:12:55.109Z","dependency_job_id":null,"html_url":"https://github.com/bw9ubwo/flask-pydanql-api","commit_stats":null,"previous_names":["jdnumm/flask-pydanql-api","bw9ubwo/flask-pydanql-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bw9ubwo/flask-pydanql-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bw9ubwo%2Fflask-pydanql-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bw9ubwo%2Fflask-pydanql-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bw9ubwo%2Fflask-pydanql-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bw9ubwo%2Fflask-pydanql-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bw9ubwo","download_url":"https://codeload.github.com/bw9ubwo/flask-pydanql-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bw9ubwo%2Fflask-pydanql-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32716100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T19:35:05.142Z","status":"ssl_error","status_checked_at":"2026-05-06T19:35:03.996Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","easy-to-use","flask","out-of-the-box","postgresql","pydanql","pydantic","python","rest-api"],"created_at":"2024-12-01T02:07:27.522Z","updated_at":"2026-05-06T23:32:12.503Z","avatar_url":"https://github.com/bw9ubwo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Flask-PydanqlAPI: Create RESTful endpoints automatically\n\n## Overview\n\nFlask-PydanqlAPI is a Flask extension designed to simplify the creation and management of RESTful APIs backed by PostgreSQL databases. Utilizing the [Pydanql](https://github.com/jdnumm/pydanql) library, this extension automates CRUD operations and provides a host of optional features for a more customized experience.\n\n## Features\n\n- **Automated CRUD Operations**: Create RESTful endpoints automatically from your Pydanql models, making it easier to handle Create, Read, Update, and Delete operations.\n  \n- **Query Customization**: Flexibility to customize which fields are queriable and which are returned in the response, letting you optimize the API according to your needs.\n\n- **Advanced Filtering**: Add an extra layer of control over the data you retrieve through advanced query filters, enabling more precise data retrieval.\n\n- **Extendable Authentication**: Although JWT authentication is not natively supported, you can easily integrate it by utilizing the filter options available.\n\n## Getting Started\n\nHere's a minimal example to show how to set up the Flask-PydanqlAPI extension without authentication and custom filtering.\n\n```python\n# Easily create a full-fledged API with all CRUD actions. Create, Read, Update\n# and Delete. Advanced search options, extensible, and even many more.\n# \n# GET Books from /books/find?year__range=1950,1960\u0026title__like=Lord\n\nfrom flask import Flask\nfrom flask_pydanql_api import PydanqlAPI, Endpoint\nfrom pydanql.model import ObjectBaseModel\n\napp = Flask(__name__)\n\n\n# Define youre Model \nclass Book(ObjectBaseModel):\n    title: str\n    author: str\n    year: int\n\n\n# Define youre API-Endpoint\nclass Books(Endpoint):\n    slug = 'books'\n    model = Book\n\n\n# Connect to your postgreSQL Database\napp.config['PYDANQL_API_DB'] = { 'database': ..., 'user': ..., 'password': ... }\napp.config['PYDANQL_API_ENDPOINTS'] = [Books]\n\nPydanqlAPI(app)\n\nif __name__ == '__main__':\n    app.run(debug=True)\n```\n\n## PostgreSQL Setup\n\nCreate a user and a database\n\n```BASH\npsql postgres # Connect to your database\n```\n\n```SQL\nCREATE DATABASE testdb;\nCREATE USER testuser WITH PASSWORD 'testpass';\nGRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;\n```\n\n## Documentation\n\n⚠️ **Early Version Warning**: This is an early version of the Flask-PydanqlAPI and is subject to changes. Although it is fully functional, future versions may introduce breaking changes. Your feedback is highly appreciated!\n\n### API Endpoints\n\n#### Find\n\n- **URL**: `/\u003ctable\u003e/find`\n- **Method**: `GET`\n  \n  - **Query Parameters**:\n    - `offset` (integer, optional): Offset for pagination.\n    - `count` (integer, optional): Number of records to fetch.\n    - `sort` (string, optional): Sorting key.\n  \n  - **Field Query Filters**:\n    - `[field]` (Type depends on the field): Direct match.\n    - `[field]__range` (integer,integer): Range query.\n    - `[field]__in` (comma-separated values): Inclusion in a set.\n    - `[field]__gt` (Type depends on the field): Greater than query.\n    - `[field]__lt` (Type depends on the field): Less than query.\n    - `[field]__like` (string): SQL LIKE query.\n  \n- **Example**: \n  - Basic: `GET /books/find?offset=0\u0026count=10`\n  - Advanced: `GET /books/find?title__like=Harry\u0026year__gt=2000`\n\n- **Returns**: A list of books matching the query parameters.\n\n\n#### Get a Single Entry\n\n- **URL**: `/\u003ctable\u003e/\u003centry_slug\u003e`\n- **Method**: `GET`\n  \n  - **Path Parameters**:\n    - `table`: The table name (e.g., `books`).\n    - `entry_slug`: The ID of the entry to fetch.\n\n- **Example**: `GET /books/1234-5678-abcd`\n\n- **Returns**: The book with the specified ID.\n\n\n#### Delete a Entry\n\n- **URL**: `/\u003ctable\u003e/\u003centry_slug\u003e`\n- **Method**: `DELETE`\n  \n  - **Path Parameters**:\n    - `table`: The table name (e.g., `books`).\n    - `entry_slug`: The ID of the entry to delete.\n\n- **Example**: `DELETE /books/1234-5678-abcd`\n\n- **Returns**: A message indicating the status of the delete operation.\n\n\n#### Create a New Entry\n\n- **URL**: `/\u003ctable\u003e/create`\n- **Method**: `POST`\n  \n  - **Path Parameters**:\n    - `table`: The table name (e.g., `books`).\n\n  - **Data Payload**: JSON object representing the new book.\n\n- **Example**: \n  ```bash\n  curl -X POST /books/create -d '{\"title\":\"New Book\", \"author\":\"Author Name\", \"year\":2021}'\n  ```\n  \n- **Returns**: Redirects to the new book entry.\n\n\n#### Update a Entry\n\n- **URL**: `/\u003ctable\u003e/\u003cslug\u003e`\n- **Method**: `PUT`\n\n  - **Path Parameters**:\n    - `table`: The table name (e.g., `books`).\n    - `slug`: The slug identifier for the book to update.\n  \n  - **Data Payload**: JSON object representing the updated book.\n\n- **Example**: \n  ```bash\n  curl -X PUT /books/1234-5678-abcd -d '{\"title\":\"Updated Book\", \"author\":\"Updated Author\", \"year\":2022}'\n  ```\n\n- **Returns**: Redirects to the updated book entry.\n\n\n\n### Defining API Endpoints and Models\n#### ObjectBaseModel Class\n\nThe `ObjectBaseModel` serves as the base class for all models in this application. It includes some fundamental fields that are automatically included in every model derived from it.\n\n##### Fields:\n\n- `slug`: A unique string identifier for each object. The `slug` is auto-generated but can be manually overwritten if necessary.\n\n##### Usage:\n\nYou can inherit from `ObjectBaseModel` when defining your models:\n\n```python\nfrom pydanql.model import ObjectBaseModel\n\nclass Book(ObjectBaseModel):\n    title: str\n    author: str\n    year: int\n```\n\n#### Endpoint Class\n\nThe `Endpoint` class is used to define API endpoints for the Flask application. Each `Endpoint` corresponds to a database table and Pydantic model that defines the shape of the data.\n\n##### Attributes:\n\n- `slug`: A string that sets the URL path for the API endpoint. Must be unique among all endpoints.\n- `model`: A Pydantic model class that specifies the structure of the data for this endpoint. This should be a subclass of `ObjectBaseModel`.\n- `allowed_query_fields`: A list of fields that can be queried directly via the API.\n- `visible_fields`: A list of fields that will be visible when fetching data via the API.\n\n##### Usage:\n\nTo define an endpoint, subclass `Endpoint` and set the `slug` and `model` attributes:\n\n```python\nfrom flask_pydanql_api import Endpoint\nfrom my_model import Book  # Assuming Book is a subclass of ObjectBaseModel\n\nclass Books(Endpoint):\n    slug = 'books'\n    model = Book\n```\n\nAfter defining your endpoints, you can register them to your Flask application using the `PydanqlAPI` class:\n\n```python\nfrom flask import Flask\nfrom flask_pydanql_api import PydanqlAPI\n\napp = Flask(__name__)\napi = PydanqlAPI(app)\n```\n\nThis will automatically generate RESTful routes for your `Endpoint` classes.\n\n\n## Examples\n### Advanced Setup with JWT and Filtering\n\nHere's an example that includes JWT authentication and custom filtering.\n\n```python\nfrom flask import Flask, request, jsonify\nfrom flask_pydanql_api import PydanqlAPI, Endpoint\nfrom pydanql.model import ObjectBaseModel\nfrom datetime import datetime\nfrom flask_jwt_extended import create_access_token, verify_jwt_in_request, get_jwt_identity, JWTManager\n\n\nclass Book(ObjectBaseModel):\n    \"\"\"This is a basic Pydanql model for books\"\"\"\n    title: str\n    author: str\n    year: int\n    owner: str\n\n    def years_since_published(self) -\u003e int:\n        \"\"\"Custom method to calculate the years since the book is published\"\"\"\n        current_year = datetime.now().year\n        return current_year - self.year + 1\n\n    def description(self) -\u003e str:\n        \"\"\"Custom method that generates a description\"\"\"\n        return f\"The Book \\\"{self.title}\\\" by {self.author} was published in the year {self.year}.\"\n\n\nclass Books(Endpoint):\n    \"\"\"Use the endpoint class for advanced configuration\"\"\"\n\n    # part of the url to accesse the table  /\u003cslug\u003e/find?title__like=Lord\n    slug = 'books'\n\n    # The object for table entries\n    model = Book\n\n    # Fields from the model that can be queried\n    allowed_query_fields = ['title', 'author', 'year']\n\n    # Fields that are exposed in the result\n    visible_fields = ['slug', 'title', 'author', 'year', 'owner']\n\n    @staticmethod\n    def _filter(query_type: str, query_table: str):\n        verify_jwt_in_request()\n        if query_type in ['find', 'get', 'create', 'update', 'delete']:\n            return {'owner': get_jwt_identity()}\n\n\napp = Flask(__name__)\n\n# Setup JWTManager\napp.config['JWT_SECRET_KEY'] = 'super-secret'\nJWTManager(app)\n\n# Setup FlaskPydanqlAPI\napp.config['PYDANQL_API_DB'] = {\n    'database': 'testdb',\n    'user': 'testuser',\n    'password': 'testpass',\n    'host': 'localhost',\n    'port': '5432'\n}\napp.config['PYDANQL_API_ENDPOINTS'] = [Books]\nPydanqlAPI(app)\n\n\n@app.route('/login', methods=['POST'])\ndef login():\n    \"\"\"Custom route to handle the login with JWTManager\"\"\"\n    if request.json is None:\n        return jsonify({\"error\": \"Bad Request\", \"message\": \"No JSON payload provided\"}), 400\n\n    username = request.json.get('username', None)\n    password = request.json.get('password', None)\n    \n    # In a real-world app, you'd validate these credentials against a database\n    if password != 'password':\n        return jsonify({'login': False}), 401\n\n    access_token = create_access_token(identity=username)\n    return jsonify(access_token=access_token), 200\n\n\nif __name__ == '__main__':\n    app.run(debug=True)\n```\n\n## Contributing\n\nWe are open to contributions. Please fork the repository and submit your pull requests!\n\n## License\n\nFlask-PydanqlAPI is licensed under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbw9ubwo%2Fflask-pydanql-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbw9ubwo%2Fflask-pydanql-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbw9ubwo%2Fflask-pydanql-api/lists"}