Skip to content

Commit

Permalink
support molecule-based data types🌽 (#384)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacksund authored Mar 6, 2023
1 parent b37b1e9 commit ad5adae
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 6 deletions.
5 changes: 4 additions & 1 deletion src/simmate/command_line/base_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,12 @@ def run_server():

logging.info("Setting up local test server...")
subprocess.run(
"django-admin runserver --settings=simmate.configuration.django.settings",
"django-admin runserver --settings=simmate.configuration.django.settings --insecure",
shell=True,
)
# BUG: we added the "--insecure" flag in order to serve static files with
# the DEBUG=False mode turned on. This makes the file serving slower though.
# https://stackoverflow.com/questions/5836674/


@simmate_app.command()
Expand Down
1 change: 1 addition & 0 deletions src/simmate/database/base_data_types/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ def from_toolkit(cls, as_dict: bool = False, **kwargs):
all_data.pop("migration_images", None)
all_data.pop("band_structure", None)
all_data.pop("density_of_states", None)
all_data.pop("molecule", None)

for parent in parents:
# Skip the parent class if it doesn't directly inherit from the
Expand Down
17 changes: 12 additions & 5 deletions src/simmate/database/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def reset_database(apps_to_migrate=APPS_TO_MIGRATE, use_prebuilt=False):
# django so that we can close everything down easily.
import psycopg2

logging.info("Connecting to database")
# Setup Postgres connection
connection = psycopg2.connect(
host=DATABASES["default"]["HOST"],
Expand All @@ -79,9 +78,12 @@ def reset_database(apps_to_migrate=APPS_TO_MIGRATE, use_prebuilt=False):
cursor = connection.cursor()

# Build out database extensions and tables
logging.info("Deleting database & building an empty one")
db_name = DATABASES["default"]["NAME"]
cursor.execute(f"DROP DATABASE IF EXISTS {db_name} WITH (FORCE);")
cursor.execute(f"DROP DATABASE IF EXISTS {db_name};")
# BUG: if others are connected I could add 'WITH (FORCE)' above.
# For now, I don't use this but should consider adding it for convenience.
# I think this is buggy with older versions of postgres (like RDkit),
# so I hold off on this for now.
cursor.execute(f"CREATE DATABASE {db_name};")

# Make the changes to the database persistent
Expand All @@ -90,7 +92,6 @@ def reset_database(apps_to_migrate=APPS_TO_MIGRATE, use_prebuilt=False):
# Close communication with the database
cursor.close()
connection.close()
logging.info("Empty database established.")

elif not using_sqlite and not using_postgres:
logging.warning(
Expand All @@ -106,7 +107,13 @@ def reset_database(apps_to_migrate=APPS_TO_MIGRATE, use_prebuilt=False):
continue

migration_dir = Path(app_config.path) / "migrations"
if migration_dir.exists():
# BUG: I need a good way to avoid deleting initial migrations that
# do things like register extensions.
# Maybe have these migrations listed as 0000_setup.py and then delete
# everything after?
# Maybe skip folders that contain a 0001_setup.py?
skip_deletes = ["rdkit", "datasets"]
if migration_dir.exists() and migration_dir.parent.name not in skip_deletes:
shutil.rmtree(migration_dir)
continue

Expand Down
42 changes: 42 additions & 0 deletions src/simmate/website/core/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,48 @@
# -*- coding: utf-8 -*-

import importlib

from django.contrib import admin
from django.urls import include, path

from simmate.configuration.django.settings import SIMMATE_APPS
from simmate.website.core import views


def get_app_urls():
# First let's find our custom simmate apps that supply a 'urls' module. We
# want to automatically make these avaialable in the web UI.

extra_url_paths = []

for app_name in SIMMATE_APPS:
# This section of code is copied from...
# simmate.workflows.utilities.get_all_workflows
# Consider making another util.
config_modulename = ".".join(app_name.split(".")[:-1])
config_name = app_name.split(".")[-1]
config_module = importlib.import_module(config_modulename)
config = getattr(config_module, config_name)
app_path = config.name
simple_name = app_path.split(".")[-1]

# check if there is a urls module in the app
# stackoverflow.com/questions/14050281
urls_found = importlib.util.find_spec(f"{app_path}.urls") is not None

if urls_found:
new_path = path(
route=f"apps/{simple_name}/",
# set the namespace so that we can easily look up app urls
# https://stackoverflow.com/questions/48608894
view=include((f"{app_path}.urls", simple_name), namespace=simple_name),
name=simple_name,
)
extra_url_paths.append(new_path)

return extra_url_paths


urlpatterns = [
#
# This is the path to the homepage (just simmate.org)
Expand Down Expand Up @@ -62,4 +100,8 @@
path(route="extras/", view=views.extras, name="extras"),
path(route="contact/", view=views.contact, name="contact"),
path(route="about/", view=views.about, name="about"),
#
# Custom Simmate apps (if present)
path(route="apps/", view=views.apps, name="apps"),
*get_app_urls(),
]
28 changes: 28 additions & 0 deletions src/simmate/website/core/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# -*- coding: utf-8 -*-

import importlib

from django.contrib.auth.decorators import login_required
from django.db.models import F
from django.shortcuts import render

from simmate.configuration.django.settings import SIMMATE_APPS
from simmate.database.third_parties import (
AflowStructure,
CodStructure,
Expand Down Expand Up @@ -108,6 +111,31 @@ def home(request):
return render(request, template, context)


def apps(request):
################
# This section of code is copied from...
# simmate.web.core.urls
# Consider making another util. I might want a SimmateConfig class that
# subclasses Django app's Config class. Add things like "learn-more" links
# and short descriptions
extra_apps = []
for app_name in SIMMATE_APPS:
config_modulename = ".".join(app_name.split(".")[:-1])
config_name = app_name.split(".")[-1]
config_module = importlib.import_module(config_modulename)
config = getattr(config_module, config_name)
app_path = config.name
simple_name = app_path.split(".")[-1]
urls_found = importlib.util.find_spec(f"{app_path}.urls") is not None
if urls_found:
extra_apps.append(simple_name)
# TODO: maybe grab a short description too?
################
context = {"extra_apps": extra_apps}
template = "core_components/apps.html"
return render(request, template, context)


def extras(request):
context = {}
template = "core_components/extras.html"
Expand Down
46 changes: 46 additions & 0 deletions src/simmate/website/templates/core_components/apps.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{% extends "core_components/site_base.html" %}

{% block tabtitle %}
Simmate
{% endblock %}

{% block banner %}
{% include "core_components/header.html"%}
{% endblock %}


{% block body %}

<!-- Header -->
<section class="pt-5 jumbotron text-center">
<div class="container">
<h1 class="jumbotron-heading">Apps</h1>
<p class="lead text-muted">Additional apps, plugins, & dashboards made with Simmate.</p>
</div>
</section>

<div class="row">

{% for app_name in extra_apps %}
<div class="col-md-4">
<div class="card" style="width: 25rem;">
<div class="card-body">
<h5 class="card-title">{{ app_name }}</h5>
<p class="card-text">
~~ an example description for this new app ~~
</p>

<a role="button" class="btn btn-primary btn-sm"
href="#" target="_blank">
Learn More...</a>
<a role="button" class="btn btn-primary btn-sm"
href="{{ app_name }}">
Try it out!</a>
</div>
</div>
</div>
{% endfor %}

</div>

{% endblock %}
7 changes: 7 additions & 0 deletions src/simmate/website/templates/core_components/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
</li>
-->

<li id="apps" class="side-nav-item">
<a href="{% url 'apps' %}" class="side-nav-link">
<i class="uil-apps"></i>
<span> Apps </span>
</a>
</li>

<li id="workflows" class="side-nav-item">
<a href="{% url 'workflows' %}" class="side-nav-link">
<i class="uil-sitemap"></i>
Expand Down

0 comments on commit ad5adae

Please sign in to comment.