From c8c66191ee52f14963e822f872f252fbab4262d1 Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Tue, 13 Sep 2022 21:52:04 +0800 Subject: [PATCH 1/3] add django support --- nebula_carina/apps.py | 13 +++++++++ nebula_carina/settings.py | 57 +++++++++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 nebula_carina/apps.py diff --git a/nebula_carina/apps.py b/nebula_carina/apps.py new file mode 100644 index 0000000..8999f3e --- /dev/null +++ b/nebula_carina/apps.py @@ -0,0 +1,13 @@ +try: + from django.apps import AppConfig + from django.utils.translation import gettext_lazy as _ + + + class NebulaCarinaConfig(AppConfig): + name = "nebula_contrib.nebula_carina" + label = "nebula_carina" + + verbose_name = _("Nebula Carina") + +except ModuleNotFoundError: + pass diff --git a/nebula_carina/settings.py b/nebula_carina/settings.py index d3ba511..d8630fe 100644 --- a/nebula_carina/settings.py +++ b/nebula_carina/settings.py @@ -1,21 +1,50 @@ -from typing import Set, Optional - +from typing import Set, Optional, Union +import typing from pydantic import BaseSettings -class DatabaseSettings(BaseSettings): - max_connection_pool_size: int = 10 - servers: Set[str] = set() - user_name: str - password: str - default_space: str = 'main' - auto_create_default_space_with_vid_desc: Optional[str] +try: + # for django + from django.conf import settings + + class DjangoCarinaDatabaseSettings(object): + + max_connection_pool_size: int = 10 + servers: Set[str] = set() + user_name: str + password: str + default_space: str = 'main' + auto_create_default_space_with_vid_desc: Optional[str] + + model_paths: Set[str] = set() + timezone_name: str = 'UTC' + + @staticmethod + def is_optional(tp): + return typing.get_origin(tp) is Union and type(None) in typing.get_args(tp) + + def __init__(self, **kwargs): + for key, type_ in DjangoCarinaDatabaseSettings.__dict__['__annotations__'].items(): + if not self.is_optional(type_) and not hasattr(DjangoCarinaDatabaseSettings, key): + assert key in kwargs, f'Setting {key} is required but not provided in CARINA_SETTINGS.' + key in kwargs and setattr(self, key, kwargs[key]) + + database_settings = DjangoCarinaDatabaseSettings(**settings.CARINA_SETTINGS) +except ModuleNotFoundError: + class DatabaseSettings(BaseSettings): + + max_connection_pool_size: int = 10 + servers: Set[str] = set() + user_name: str + password: str + default_space: str = 'main' + auto_create_default_space_with_vid_desc: Optional[str] - model_paths: Set[str] = set() - timezone_name: str = 'UTC' + model_paths: Set[str] = set() + timezone_name: str = 'UTC' - class Config: - env_prefix = 'nebula_' + class Config: + env_prefix = 'nebula_' -database_settings = DatabaseSettings() + database_settings = DatabaseSettings() From 4b44f5be3cefe9847ba725d667145b8c5694a2df Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Tue, 13 Sep 2022 22:20:44 +0800 Subject: [PATCH 2/3] fix readme & setup --- README.md | 58 +++++++++++++++++++++++++++++++++++++++---- nebula_carina/apps.py | 2 +- setup.py | 2 +- 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 91e2eb0..089f612 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # nebula-carina -Nebula Carina is a **Pydantic** based **Fastapi** friendly **ORM** framework for graph database **Nebula Graph**. +Nebula Carina is a **Pydantic** based **ORM** framework for graph database **Nebula Graph**. This project is designed to provide an easy-to-use orm package for the Nebula Graph database for Python development, especially web application development. Nebula Graph is a powerful graph database, the only graph database solution in the world that can accommodate hundreds of billions of vertices and trillions of edges and provide millisecond-level query latency. -The goals of this project include providing an object-oriented description of the database structure, concise Query statements, and JSONizable results. In particular, I used the pydantic library with the expectation that this library can be used in conjunction with the fastapi framework. +The goals of this project include providing an object-oriented description of the database structure, concise Query statements, and JSONizable results. In particular, I used the pydantic library with the expectation that this library can be used in conjunction with any modern python web framework. This project is based on the official package nebula-python https://github.com/vesoft-inc/nebula-python. @@ -26,7 +26,35 @@ install using `pip` ## Configuration -Please configure environment variables. +### By Django Settings + +If you are using Django framework, then add `nebula_carina` to `INSTALLED_APPS`: +```python +INSTALLED_APPS = [ + ... + 'nebula_carina', + ... +] +``` + +Then, setup the `CARINA_SETTINGS` in your **settings.py** file as following: +```python +CARINA_SETTINGS = { + "auto_create_default_space_with_vid_desc": "FIXED_STRING(20)", + "default_space": "main", + "max_connection_pool_size": 10, + "model_paths": ["nebula.carina"], + "user_name": "root", + "password": "1234", + "servers": ["192.168.31.248:9669"], + "timezone_name": "UTC", +} +``` + + +### By Environment Variables + +Please configure environment variables if you are not using Django. ``` nebula_servers='["192.168.1.10:9669"]' nebula_user_name=root @@ -216,7 +244,8 @@ ModelBuilder.match( ) ``` -### Fastapi +### Framework Specific Examples +#### Fastapi If you are using fastapi, then serialization and deserialization are already handled by the repo. For example, in your api functions, you are welcomed to use the result of data model or the model builder in your return function. It's very easy to use! ```python from fastapi import FastAPI @@ -250,6 +279,24 @@ async def what_a_complex_human_relation(character_id: str): ) ``` +#### Django +Basically things are the same as in fastapi except that you have to use `.dict()` method to serialize a model before using it in response. +Match method would be harder to use. A wrapper that support `.dict()` method will be implemented in 0.3.0. +```python +from example.models import VirtualCharacter +from django.http import JsonResponse + +def some_view(request, character_id: str): + vr = VirtualCharacter.objects.get(character_id) + # make sure that use .dict() function to serialize the result + return JsonResponse(vr.dict()) + +``` + +#### Flask +Flask usage is quite similar to the Django usage. Basically use `.dict()` function to serialize the model. + + ## TODO List - [ ] Indexes - [ ] TTL on schema @@ -258,4 +305,5 @@ async def what_a_complex_human_relation(character_id: str): - [ ] More abstractions on different scenarios - [ ] Default values for schema models - [ ] Generic Vertex Model -- [ ] Django Support \ No newline at end of file +- [x] Django Support +- [ ] Match Result Wrapper \ No newline at end of file diff --git a/nebula_carina/apps.py b/nebula_carina/apps.py index 8999f3e..b958f6b 100644 --- a/nebula_carina/apps.py +++ b/nebula_carina/apps.py @@ -4,7 +4,7 @@ class NebulaCarinaConfig(AppConfig): - name = "nebula_contrib.nebula_carina" + name = "nebula_carina" label = "nebula_carina" verbose_name = _("Nebula Carina") diff --git a/setup.py b/setup.py index 25c41ae..933597b 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='nebula-carina', - version='0.2.0', + version='0.2.1', author='Sword Elucidator', author_email='nagisa940216@gmail.com', url='https://github.com/SwordElucidator/nebula-carina', From 59661ada8ec5f174fbc4c6fc8f2f9b99b99263da Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Tue, 13 Sep 2022 22:29:11 +0800 Subject: [PATCH 3/3] add todos --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 089f612..26910dd 100644 --- a/README.md +++ b/README.md @@ -305,5 +305,6 @@ Flask usage is quite similar to the Django usage. Basically use `.dict()` functi - [ ] More abstractions on different scenarios - [ ] Default values for schema models - [ ] Generic Vertex Model -- [x] Django Support -- [ ] Match Result Wrapper \ No newline at end of file +- [x] Basic Django Support + - [ ] Django management.py + - [ ] Match Result Wrapper