Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fccc meetup api v1 #1

Open
wants to merge 64 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
ceba030
Attempting to sync commit histories with Gregg's changes
takosuper1 Sep 6, 2024
b5bd956
added tutorial modules
takosuper1 Sep 6, 2024
38904c2
removed tutorial steps. Not necessary to be here
takosuper1 Sep 6, 2024
f26061f
setup venv
takosuper1 Sep 6, 2024
fd821a6
added all items for module_1 for setup
takosuper1 Sep 6, 2024
1b06c69
moved requirements.txt to backend. Added imports, connections to .env…
takosuper1 Sep 6, 2024
5635a62
added some constants variables in the setttings.py file
takosuper1 Sep 6, 2024
02c38de
added settings to router.py
takosuper1 Sep 6, 2024
d6acb2e
fixed django migrations issue in setup. Needed to change 'core' in in…
takosuper1 Sep 9, 2024
47179aa
playing with file structure. Might have to redo something so that I h…
takosuper1 Sep 9, 2024
0c7f620
Updated to match drf file structure
takosuper1 Sep 10, 2024
7ae81e3
Adding Module_3
takosuper1 Sep 10, 2024
f2fc2b7
Renamed directory inside backend to match the description of what its…
takosuper1 Sep 10, 2024
7bac044
added model to models.py
takosuper1 Sep 17, 2024
edaeaae
added serializers, abstract model for UUID
takosuper1 Sep 17, 2024
b36ea16
added views and url patterns.
takosuper1 Sep 17, 2024
b71a94e
registered contact in admin.py
takosuper1 Sep 17, 2024
3bc03da
Changed drf_course references to FCCC_Meetup2Discord_API
takosuper1 Sep 17, 2024
70be72d
added .env file
takosuper1 Sep 17, 2024
2eabcbc
Fixed migration issue. Reinstalled several modules.
takosuper1 Sep 17, 2024
5ad816b
Using complete branch to start process over to hopefully mitigate som…
takosuper1 Sep 18, 2024
06d5186
Got docker running correctly. Changed the distro it was pulling from …
takosuper1 Sep 18, 2024
bf3d318
New branch to start build
takosuper1 Sep 24, 2024
f5fe02d
added files from TWT project. Changed names of two directories: 1) Dj…
takosuper1 Sep 24, 2024
399cf7a
added dotenv package and created .env file.
takosuper1 Sep 24, 2024
5c431f6
Restarting process. Copy and paste causes too many issues.
takosuper1 Sep 24, 2024
54c1c83
added django project and api app
takosuper1 Sep 24, 2024
1fff25e
Created basic model for ical data based on text file from john riley
takosuper1 Sep 24, 2024
75b3adc
added serializer file and utils file. Parser in utils file. also adde…
takosuper1 Sep 24, 2024
19dd932
made model migrations
takosuper1 Sep 24, 2024
710f0e4
added relative path.
takosuper1 Sep 24, 2024
9e8f0f0
finshed writing first test: test_connection_to_ical_file
takosuper1 Sep 26, 2024
98a613a
created second test: test_output_of_parse_ical_file: verified the dic…
takosuper1 Sep 26, 2024
c2b8156
Fixed parse_ical_file function to be able to read strings with no or …
takosuper1 Sep 26, 2024
357e220
cleaned up printing messages
takosuper1 Sep 26, 2024
454b858
first comment in utils.py to be more accurate
takosuper1 Sep 26, 2024
5ef6b55
Started mapping process to object model.
takosuper1 Sep 26, 2024
fbf3d73
added mapping function and got tests to pass. Added comment to models…
takosuper1 Oct 3, 2024
0d0cba6
Set timezone in settings to timezone.now from django utils. Fixed iss…
takosuper1 Oct 3, 2024
562301f
Still have a timezone issue because I am wanting to set it automatica…
takosuper1 Oct 3, 2024
47b3a3d
upda
takosuper1 Oct 7, 2024
ecea975
Fixed model errors. Data is being saved. Timezone warning persists.
takosuper1 Oct 7, 2024
9121979
added a test to verify an item is saved in the database
takosuper1 Oct 7, 2024
20c7f93
added test to verify using the bulk create
takosuper1 Oct 7, 2024
3386058
added three functions: delete one, delete a list, get one from databa…
takosuper1 Oct 7, 2024
2c90d03
Restructured files for utils. Had LLM take google app script from jon…
takosuper1 Oct 7, 2024
02a19e3
copied and had llm translate js into python for the get request to me…
takosuper1 Oct 8, 2024
945526e
trimmed the code for get_ical.py. Got it to request and return the da…
takosuper1 Oct 8, 2024
1081f72
Combining in attempt to connect get_ical
takosuper1 Oct 9, 2024
ace177d
fixed parser to parse ical file directly from meetup api using icalen…
takosuper1 Oct 10, 2024
4102908
all tests pass. Still have not suppressed the timezone warning.
takosuper1 Oct 10, 2024
beb10a0
server is up. Added dotenv with settings for origin, hosts, and secre…
takosuper1 Oct 10, 2024
0aff0c0
API get route working with api key.
takosuper1 Oct 10, 2024
36643f7
halfway finished with api security. this is just in case the llm is c…
takosuper1 Oct 11, 2024
2b997da
Got host ,origin, and api key to work now. Need to tweak postman beca…
takosuper1 Oct 11, 2024
777e688
removed unused check origin code
takosuper1 Oct 11, 2024
64b579b
removed cors from settings.py
takosuper1 Oct 12, 2024
28f45e9
added update to database in parsing_ical. Have an error. Might be nul…
takosuper1 Oct 12, 2024
3ef52b4
Refactoring parsing and get ical functions and putting them in better…
takosuper1 Oct 12, 2024
178f7fa
Refactored functions for CRUD, Parsing, and getting icalendar
takosuper1 Oct 14, 2024
156a2a3
connected data flow process to get request and limited the meetup api…
takosuper1 Oct 14, 2024
0d18475
added logger and error handling for views, get_ical, database crud, a…
takosuper1 Oct 14, 2024
80f1eed
updated logger in get_ical to reflect what is going on.
takosuper1 Oct 14, 2024
1e218fc
updated with dockerfile revised settings
takosuper1 Oct 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
*.pyc
*.pyo
*.mo
*.db
*.css.map
*.egg-info
*.sql.gz
.cache
.project
.idea
.pydevproject
.idea/workspace.xml
.DS_Store
.git/
.gitignore
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
staticfiles
39 changes: 14 additions & 25 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
staticfiles/
mediafiles/
logs/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -55,6 +59,7 @@ cover/
*.mo
*.pot


# Django stuff:
*.log
local_settings.py
Expand Down Expand Up @@ -94,24 +99,7 @@ ipython_config.py
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
Expand All @@ -123,12 +111,16 @@ celerybeat.pid

# Environments
.env
.env.prod
.env.dev
.env.staging
.venv
env/
# env/
venv/
ENV/
env.bak/
venv.bak/
launch.json

# Spyder project settings
.spyderproject
Expand All @@ -154,9 +146,6 @@ dmypy.json
# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.DS_Store

*.dump
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"python.testing.unittestArgs": [
"-v",
"-s",
"./MeetupUpdateAPI",
"-p",
"test*.py"
],
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": true
}
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Use an official Python runtime as the base image
FROM python:3.9-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DJANGO_ALLOWED_HOSTS=0.0.0.0
# ENV ALLOWED_ORIGIN=https://fcccolumbus.com
ENV SECRET_KEY="Pf+6tX!5CWTcCK}3N"
ENV API_KEY="s*2NQT2!iT4uhr&'q"
ENV MEETUP_ID="276932425"
ENV MEETUP_EXPORT_URL="https://www.meetup.com/techlifecolumbus/events/ical/"


# Set the working directory in the container
WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*

# Install Python dependencies
COPY requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt

# Install Gunicorn
RUN pip install gunicorn

# Copy the project code into the container
COPY . .

# Collect static files
RUN python MeetupUpdateAPI/manage.py collectstatic --noinput

# Run the application
CMD ["gunicorn", "--chdir", "MeetupUpdateAPI", "--bind", "0.0.0.0:8000", "MeetupUpdateAPI.wsgi:application"]

Empty file.
16 changes: 16 additions & 0 deletions MeetupUpdateAPI/MeetupUpdateAPI/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
ASGI config for MeetupUpdateAPI project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MeetupUpdateAPI.settings')

application = get_asgi_application()
38 changes: 38 additions & 0 deletions MeetupUpdateAPI/MeetupUpdateAPI/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from rest_framework import authentication
from rest_framework import exceptions
from django.conf import settings
from django.contrib.auth.models import User
import logging


logger = logging.getLogger(__name__)

class APIKeyAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):

# TODO: add when production url is ready
# # Check Host header
# host = request.META.get('HTTP_HOST')
# if host not in settings.ALLOWED_HOSTS:
# logger.warning(f"Invalid host: {host}")
# raise exceptions.AuthenticationFailed('Invalid host')

api_key = request.META.get('HTTP_X_API_KEY')
logger.info(f"API key: {api_key} is authentic")
if not api_key:
logger.warning(f"API key not provided from {request.META.get('REMOTE_ADDR')}")
return None
if api_key != settings.API_KEY:
logger.warning(
"Invalid API key attempt - Host: %s, Path: %s, Method: %s, IP: %s",
request.get_host(),
request.path,
request.method,
request.META.get('REMOTE_ADDR')
)
raise exceptions.AuthenticationFailed('Invalid API key')


logger.info(f"{request.get_host()}'s authentication successful")
user, _ = User.objects.get_or_create(username='api_user')
return (user, None)
174 changes: 174 additions & 0 deletions MeetupUpdateAPI/MeetupUpdateAPI/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
"""
Django settings for MeetupUpdateAPI project.

Generated by 'django-admin startproject' using Django 5.1.1.

For more information on this file, see
https://docs.djangoproject.com/en/5.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
"""

from pathlib import Path
import os
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# Get the SECRET_KEY from the environment
SECRET_KEY = os.getenv('SECRET_KEY')
ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '').split(' ')
CORS_ALLOWED_ORIGIN = os.getenv('ALLOWED_ORIGIN', '').split(' ')
API_KEY = os.getenv('API_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

# Create a logs directory
LOGS_DIR = os.environ.get('DJANGO_LOGS_DIR', os.path.join(BASE_DIR, 'logs'))
os.makedirs(LOGS_DIR, exist_ok=True)

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
},
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(LOGS_DIR, 'django.log'),
'maxBytes': 1024 * 1024 * 5, # 5 MB
'backupCount': 5,
'formatter': 'verbose',
},
},
'loggers': {
'': { # root logger
'handlers': ['file'],
'level': 'INFO',
},
},
}

# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"api",
"rest_framework",
"rest_framework.authtoken",
# "corsheaders",
]




REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'MeetupUpdateAPI.auth.APIKeyAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 'corsheaders.middleware.CorsMiddleware',
]

ROOT_URLCONF = 'MeetupUpdateAPI.urls'

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

WSGI_APPLICATION = 'MeetupUpdateAPI.wsgi.application'


# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}


# Password validation
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]


# Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Loading