add node endpoint to list nodes of type
This commit is contained in:
parent
b9d22bede1
commit
9ad0a31afc
97
api.py
97
api.py
@ -1,80 +1,49 @@
|
|||||||
from flask import Flask, request, jsonify
|
# app.py
|
||||||
import requests
|
from flask import Flask, jsonify, request
|
||||||
from neo4j import GraphDatabase
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from cachetools import TTLCache
|
from neo4j import GraphDatabase
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
import importlib.util
|
||||||
|
|
||||||
# Set up basic configuration for logging
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# Load environment variables from .env file
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
# Retrieve Neo4j connection details and API key
|
|
||||||
NEO4J_URI = os.getenv('NEO4J_URI')
|
|
||||||
NEO4J_USER = os.getenv('NEO4J_USER')
|
|
||||||
NEO4J_PASSWORD = os.getenv('NEO4J_PASSWORD')
|
|
||||||
CONGRESS_API_KEY = os.getenv('CONGRESS_API_KEY')
|
|
||||||
|
|
||||||
if not NEO4J_URI or not NEO4J_USER or not NEO4J_PASSWORD:
|
|
||||||
raise ValueError("Neo4j connection details not found in .env file")
|
|
||||||
if not CONGRESS_API_KEY:
|
|
||||||
raise ValueError("Congress API key not found in .env file")
|
|
||||||
|
|
||||||
# Initialize Neo4j driver
|
|
||||||
driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
|
|
||||||
|
|
||||||
# Initialize caches
|
|
||||||
neo4j_cache = TTLCache(maxsize=100, ttl=3600) # Cache for 1 hour
|
|
||||||
congress_api_cache = TTLCache(maxsize=100, ttl=3600) # Cache for 1 hour
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
app.wsgi_app = ProxyFix(app.wsgi_app)
|
||||||
|
|
||||||
@app.route('/sponsored_legislation', methods=['GET'])
|
# Configure logging
|
||||||
def get_sponsored_legislation():
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
bioguide_id = request.args.get('bioguideId')
|
|
||||||
if not bioguide_id:
|
|
||||||
return jsonify({"error": "bioguideId is required"}), 400
|
|
||||||
|
|
||||||
logger.info(f"Fetching sponsored legislation for member with bioguideId {bioguide_id}")
|
# Neo4j configuration
|
||||||
|
NEO4J_URI = os.getenv("NEO4J_URI")
|
||||||
|
NEO4J_USER = os.getenv("NEO4J_USER")
|
||||||
|
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")
|
||||||
|
|
||||||
# Check cache before making API request
|
def get_driver():
|
||||||
cached_legislation = congress_api_cache.get(bioguide_id)
|
return GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
|
||||||
if cached_legislation:
|
|
||||||
logger.info(f"Using cached sponsored legislation for bioguideId {bioguide_id}")
|
|
||||||
return jsonify({"message": "Sponsored legislation retrieved from cache", "legislations": cached_legislation})
|
|
||||||
|
|
||||||
|
# Function to dynamically import and register blueprints
|
||||||
|
def load_blueprints_from_directory(directory):
|
||||||
|
for filename in os.listdir(directory):
|
||||||
|
if filename.endswith('.py') and not filename.startswith('__'):
|
||||||
|
module_name = filename[:-3] # Remove .py extension
|
||||||
|
file_path = os.path.join(directory, filename)
|
||||||
|
|
||||||
|
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
||||||
|
module = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
|
||||||
@app.route('/persons', methods=['GET'])
|
if hasattr(module, 'bp'):
|
||||||
def list_persons():
|
app.register_blueprint(module.bp)
|
||||||
logger.info("Listing all person nodes from Neo4j")
|
logging.info(f'Registered blueprint: {module.bp.name}')
|
||||||
|
|
||||||
# Check cache before querying Neo4j
|
# Load blueprints from the endpoints directory
|
||||||
cached_persons = neo4j_cache.get('all_persons')
|
load_blueprints_from_directory(os.path.join(os.path.dirname(__file__), 'endpoints'))
|
||||||
if cached_persons:
|
|
||||||
logger.info("Using cached list of persons")
|
|
||||||
return jsonify({"message": "Persons retrieved from cache", "persons": cached_persons})
|
|
||||||
|
|
||||||
with driver.session() as session:
|
@app.route('/')
|
||||||
query = "MATCH (p:Person) RETURN p"
|
def index():
|
||||||
logger.info(f"Executing Neo4j query to list all person nodes: {query}")
|
return jsonify({"message": "Welcome to the Flask API!"})
|
||||||
result = session.run(query)
|
|
||||||
|
|
||||||
persons = [record['p'] for record in result]
|
|
||||||
person_list = []
|
|
||||||
for person in persons:
|
|
||||||
node_properties = {key: value for key, value in person.items()}
|
|
||||||
person_list.append(node_properties)
|
|
||||||
|
|
||||||
# Cache the response
|
|
||||||
neo4j_cache['all_persons'] = person_list
|
|
||||||
logger.info("Cached list of all persons")
|
|
||||||
|
|
||||||
return jsonify({"message": "Persons listed successfully", "persons": person_list})
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
app.run(debug=True)
|
||||||
|
44
api/api.py
Normal file
44
api/api.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# app.py
|
||||||
|
from flask import Flask, jsonify, request
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from neo4j import GraphDatabase
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
import importlib.util
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.wsgi_app = ProxyFix(app.wsgi_app)
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
|
||||||
|
# Neo4j configuration
|
||||||
|
NEO4J_URI = os.getenv("NEO4J_URI")
|
||||||
|
NEO4J_USER = os.getenv("NEO4J_USER")
|
||||||
|
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")
|
||||||
|
|
||||||
|
def get_driver():
|
||||||
|
return GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
|
||||||
|
|
||||||
|
# Function to dynamically import and register blueprints
|
||||||
|
def load_blueprints_from_directory(directory):
|
||||||
|
for filename in os.listdir(directory):
|
||||||
|
if filename.endswith('.py') and not filename.startswith('__'):
|
||||||
|
module_name = filename[:-3] # Remove .py extension
|
||||||
|
file_path = os.path.join(directory, filename)
|
||||||
|
|
||||||
|
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
||||||
|
module = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
|
||||||
|
if hasattr(module, 'bp'):
|
||||||
|
app.register_blueprint(module.bp)
|
||||||
|
|
||||||
|
# Load blueprints
|
||||||
|
load_blueprints_from_directory('endpoints')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True)
|
55
api/app.py
Normal file
55
api/app.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# app.py
|
||||||
|
from flask import Flask, jsonify, request
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from neo4j import GraphDatabase
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
import importlib.util
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.wsgi_app = ProxyFix(app.wsgi_app)
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
|
||||||
|
# Neo4j configuration
|
||||||
|
NEO4J_URI = os.getenv("NEO4J_URI")
|
||||||
|
NEO4J_USER = os.getenv("NEO4J_USER")
|
||||||
|
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")
|
||||||
|
|
||||||
|
def get_driver():
|
||||||
|
return GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
|
||||||
|
|
||||||
|
# Custom logger for Neo4j queries
|
||||||
|
neo4j_logger = logging.getLogger('Neo4jLogger')
|
||||||
|
neo4j_logger.setLevel(logging.INFO)
|
||||||
|
neo4j_handler = logging.StreamHandler()
|
||||||
|
neo4j_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
neo4j_handler.setFormatter(neo4j_formatter)
|
||||||
|
neo4j_logger.addHandler(neo4j_handler)
|
||||||
|
|
||||||
|
# Attach the logger to the app instance
|
||||||
|
app.neo4j_logger = neo4j_logger
|
||||||
|
|
||||||
|
# Function to dynamically import and register blueprints
|
||||||
|
def load_blueprints_from_directory(directory):
|
||||||
|
for filename in os.listdir(directory):
|
||||||
|
if filename.endswith('.py') and not filename.startswith('__'):
|
||||||
|
module_name = filename[:-3] # Remove .py extension
|
||||||
|
file_path = os.path.join(directory, filename)
|
||||||
|
|
||||||
|
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
||||||
|
module = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
|
||||||
|
if hasattr(module, 'bp'):
|
||||||
|
app.register_blueprint(module.bp)
|
||||||
|
|
||||||
|
# Load blueprints
|
||||||
|
load_blueprints_from_directory('endpoints')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True)
|
30
api/endpoints/nodes.py
Normal file
30
api/endpoints/nodes.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# endpoints/nodes.py
|
||||||
|
from flask import Blueprint, request, jsonify
|
||||||
|
from app import get_driver, neo4j_logger
|
||||||
|
|
||||||
|
bp = Blueprint('nodes', __name__)
|
||||||
|
|
||||||
|
@bp.route('/nodes')
|
||||||
|
def get_nodes():
|
||||||
|
node_type = request.args.get('type')
|
||||||
|
|
||||||
|
if not node_type:
|
||||||
|
return jsonify({"error": "Node type is required"}), 400
|
||||||
|
|
||||||
|
driver = get_driver()
|
||||||
|
with driver.session() as session:
|
||||||
|
query = f"MATCH (n:{node_type}) RETURN n"
|
||||||
|
neo4j_logger.info(f"Executing query: {query}")
|
||||||
|
nodes = session.run(query)
|
||||||
|
|
||||||
|
# Convert the nodes to a list of dictionaries
|
||||||
|
nodes_list = [
|
||||||
|
{
|
||||||
|
'id': record['n'].id,
|
||||||
|
'labels': list(record['n'].labels),
|
||||||
|
**{key: value for key, value in record['n'].items()}
|
||||||
|
}
|
||||||
|
for record in nodes
|
||||||
|
]
|
||||||
|
|
||||||
|
return jsonify({"nodes": nodes_list})
|
Loading…
Reference in New Issue
Block a user