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

Pulling main up to speed. #579

Merged
merged 21 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5bc2e18
Merge pull request #569 from open5e/main
augustjohnson Oct 10, 2024
2d9e4c7
Address self-hosting.
augustjohnson Oct 13, 2024
0968bea
Updating to address #405
augustjohnson Oct 13, 2024
730a662
Merge pull request #571 from open5e/409-how-to-build-and-self-host
augustjohnson Oct 13, 2024
b1fcc5b
Fixing some accumulated bugs.
augustjohnson Oct 16, 2024
c3e6fc3
Tests
augustjohnson Oct 16, 2024
a7d9c91
Merge pull request #573 from open5e/572-api-v2-weapon-model-not-retur…
augustjohnson Oct 16, 2024
c56441b
Resolving some item data issues.
augustjohnson Oct 18, 2024
63b1439
Adding damage immunities to items per the SRD.
augustjohnson Oct 18, 2024
ec25dbd
Adding weights to armors.
augustjohnson Oct 18, 2024
c5b1dec
Adding a draft of armor category.
augustjohnson Oct 18, 2024
3fd0ee0
Fixing approval tests.
augustjohnson Oct 18, 2024
c6588fd
Merge pull request #575 from open5e/574-api-v2-some-magic-items-marke…
augustjohnson Oct 18, 2024
ff0b53d
Organizing urls a bit better. Should be non-functional change.
augustjohnson Oct 19, 2024
c769682
Url structure changes.
augustjohnson Oct 19, 2024
1478119
Organizing urls a bit better. Should be non-functional change.
augustjohnson Oct 19, 2024
f308bca
Url structure changes.
augustjohnson Oct 19, 2024
88da113
Merge branch 'openapi_schema_definition' of github.com:open5e/open5e-…
augustjohnson Oct 19, 2024
640c201
Adding two distinct schemas.
augustjohnson Oct 19, 2024
dc8f94a
Hoping this will do the trick.
augustjohnson Oct 19, 2024
0ec09d4
Merge pull request #578 from open5e/openapi_schema_definition
augustjohnson Oct 19, 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
3 changes: 2 additions & 1 deletion .github/workflows/rdme-openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ jobs:
- name: Run `openapi` command 🚀
uses: readmeio/rdme@v8
with:
rdme: openapi openapi-schema.yml --key=${{ secrets.README_API_KEY }} --id=641f6d9e0ffbcd06c0e7343c
rdme: openapi openapi-schema-v1.yml --key=${{ secrets.README_API_KEY }} --id=641f6d9e0ffbcd06c0e7343c
rdme: openapi openapi-schema-v2.yml --key=${{ secrets.README_API_KEY }} --id=641f6d9e0ffbcd06c0e7343c
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ Run the server locally. This server is only for development and shall __not__ be
pipenv run python manage.py runserver
```

If you need to run the server on another port, add the port number as an argument.
### Self-hosting
If you would like to host the API yourself locally, we suggest using gunicorn as your wsgi server. Below is an equivalent command to what we use in production, which makes the server available at `http://localhost:8888`.

```bash
pipenv run python manage.py runserver $PORT
gunicorn -b :8888 server.wsgi:application
```

You can use our Dockerfile as inspiration, but it likely will not work without significant edits to your operating environment. We have customized our production environment to use it.

## Building the OAS file

Expand Down
4 changes: 3 additions & 1 deletion api/schema_generator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from rest_framework.schemas.openapi import SchemaGenerator
'''from rest_framework.schemas.openapi import SchemaGenerator
from rest_framework.schemas.openapi import AutoSchema

# Adds additional metadata onto an OAS operation. Attach this to your view and provide the necessary constructor args.
Expand All @@ -21,6 +21,7 @@ def get_operation(self, path, method):
oldOperation = super().get_operation(path, method)

# I can't find a version of DRF that support summaries
if path.startswith('/v1/'): return oldOperation
oldOperation['summary'] = self.extra_info['summary'][path]

# Future versions of DRF support tags
Expand Down Expand Up @@ -61,3 +62,4 @@ def get_schema(self, *args, **kwargs):
# This isn't a real endpoint, so we remove it from the schema
schema['paths'].pop('/search/{id}/')
return schema
'''
17 changes: 9 additions & 8 deletions api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ def __init__(self, *args, **kwargs):

# The request doesn't exist when generating an OAS file, so we have to check that first
if 'request' in self.context:
fields = self.context['request'].query_params.get('fields')
if fields:
fields = fields.split(',')
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
if self.context['request'] is not None:
fields = self.context['request'].query_params.get('fields')
if fields:
fields = fields.split(',')
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)

class DynamicFieldsHyperlinkedModelSerializer(
DynamicFieldsModelSerializer, serializers.HyperlinkedModelSerializer
Expand Down
28 changes: 28 additions & 0 deletions api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from rest_framework import routers
from django.conf.urls import include
from django.urls import path

from api import views

router = routers.DefaultRouter()
router.register(r'manifest', views.ManifestViewSet)
router.register(r'spells', views.SpellViewSet)
router.register(r'spelllist',views.SpellListViewSet)
router.register(r'monsters', views.MonsterViewSet)
router.register(r'documents', views.DocumentViewSet)
router.register(r'backgrounds', views.BackgroundViewSet)
router.register(r'planes', views.PlaneViewSet)
router.register(r'sections', views.SectionViewSet)
router.register(r'feats', views.FeatViewSet)
router.register(r'conditions', views.ConditionViewSet)
router.register(r'races',views.RaceViewSet)
router.register(r'classes',views.CharClassViewSet)
router.register(r'magicitems',views.MagicItemViewSet)
router.register(r'weapons',views.WeaponViewSet)
router.register(r'armor',views.ArmorViewSet)

urlpatterns = [
path('', include(router.urls)), #Consider removing this after a while.
path('version/', views.get_version, name="version"),
path('v1/', include(router.urls))
]
126 changes: 1 addition & 125 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from api import models
from api import serializers
from api import filters
from api.schema_generator import CustomSchema
#from api.schema_generator import CustomSchema


class ManifestViewSet(viewsets.ReadOnlyModelViewSet):
Expand All @@ -28,13 +28,6 @@ class ManifestViewSet(viewsets.ReadOnlyModelViewSet):
automatically downloads data from Open5e, you can periodically check
the manifests to determine whether your data is out of date.
"""
schema = CustomSchema(
summary={
'/manifest/': 'List Manifests',
'/manifest/{id}/': 'Retrieve Manifest',
},
tags=['Manifests'],
)
queryset = models.Manifest.objects.all().order_by("pk")
serializer_class = serializers.ManifestSerializer

Expand Down Expand Up @@ -102,18 +95,6 @@ class DocumentViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of documents.
retrieve: API endpoint for returning a particular document.
"""
schema = CustomSchema(
summary={
'/documents/': 'List Documents',
'/documents/{id}/': 'Retrieve Document',
},
tags=['Documents'],
query={
'slug': 'A short, human readable string uniquely identifying this document',
'title': 'A short descriptive title of this document',
'organization': 'The organization that published the document',
'license': 'The license under which the document is published',
})
queryset = models.Document.objects.all().order_by("pk")
serializer_class = serializers.DocumentSerializer
search_fields = ['title', 'desc']
Expand All @@ -130,13 +111,6 @@ class SpellViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of spells.
retrieve: API endpoint for returning a particular spell.
"""
schema = CustomSchema(
summary={
'/spells/': 'List Spells',
'/spells/{slug}/': 'Retrieve Spell',
},
tags=['Spells']
)
queryset = models.Spell.objects.all().order_by("pk")
filterset_class=filters.SpellFilter
serializer_class = serializers.SpellSerializer
Expand All @@ -163,13 +137,6 @@ class SpellListViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of spell lists.
retrieve: API endpoint for returning a particular spell list.
"""
schema = CustomSchema(
summary={
'/spelllist/': 'List Spell Lists',
'/spelllist/{slug}/': 'Retrieve Spell List',
},
tags=['SpellList']
)
queryset = models.SpellList.objects.all().order_by("pk")
serializer_class = serializers.SpellListSerializer
filterset_class = filters.SpellListFilter
Expand All @@ -181,13 +148,6 @@ class MonsterViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of monsters.
retrieve: API endpoint for returning a particular monster.
"""
schema = CustomSchema(
summary={
'/monsters/': 'List Monsters',
'/monsters/{slug}/': 'Retrieve Monster',
},
tags=['Monsters']
)
queryset = models.Monster.objects.all().order_by("pk")
filterset_class = filters.MonsterFilter

Expand All @@ -199,13 +159,6 @@ class BackgroundViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of backgrounds.
retrieve: API endpoint for returning a particular background.
"""
schema = CustomSchema(
summary={
'/backgrounds/': 'List Backgrounds',
'/backgrounds/{slug}/': 'Retrieve Background',
},
tags=['Backgrounds']
)
queryset = models.Background.objects.all().order_by("pk")
serializer_class = serializers.BackgroundSerializer
ordering_fields = '__all__'
Expand All @@ -219,13 +172,6 @@ class PlaneViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of planes.
retrieve: API endpoint for returning a particular plane.
"""
schema = CustomSchema(
summary={
'/planes/': 'List Planes',
'/planes/{slug}/': 'Retrieve Plane',
},
tags=['Planes']
)
queryset = models.Plane.objects.all().order_by("pk")
serializer_class = serializers.PlaneSerializer
filterset_class = filters.PlaneFilter
Expand All @@ -237,13 +183,6 @@ class SectionViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of sections.
retrieve: API endpoint for returning a particular section.
"""
schema = CustomSchema(
summary={
'/sections/': 'List Sections',
'/sections/{slug}/': 'Retrieve Section',
},
tags=['Sections']
)
queryset = models.Section.objects.all().order_by("pk")
serializer_class = serializers.SectionSerializer
ordering_fields = '__all__'
Expand All @@ -257,13 +196,6 @@ class FeatViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of feats.
retrieve: API endpoint for returning a particular feat.
"""
schema = CustomSchema(
summary={
'/feats/': 'List Feats',
'/feats/{slug}/': 'Retrieve Feat',
},
tags=['Feats']
)
queryset = models.Feat.objects.all().order_by("pk")
serializer_class = serializers.FeatSerializer
filterset_class = filters.FeatFilter
Expand All @@ -275,13 +207,6 @@ class ConditionViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of conditions.
retrieve: API endpoint for returning a particular condition.
"""
schema = CustomSchema(
summary={
'/conditions/': 'List Conditions',
'/conditions/{slug}/': 'Retrieve Condition',
},
tags=['Conditions']
)
queryset = models.Condition.objects.all().order_by("pk")
serializer_class = serializers.ConditionSerializer
search_fields = ['name', 'desc']
Expand All @@ -293,13 +218,6 @@ class RaceViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of races.
retrieve: API endpoint for returning a particular race.
"""
schema = CustomSchema(
summary={
'/races/': 'List Races',
'/races/{slug}/': 'Retrieve Race',
},
tags=['Races']
)
queryset = models.Race.objects.all().order_by("pk")
serializer_class = serializers.RaceSerializer
filterset_class = filters.RaceFilter
Expand All @@ -312,13 +230,6 @@ class SubraceViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint that allows viewing of Subraces.
retrieve: API endpoint for returning a particular subrace.
"""
schema = CustomSchema(
summary={
'/subraces/': 'List Subraces',
'/subraces/{slug}/': 'Retrieve Subrace',
},
tags=['Subraces']
)
queryset = models.Subrace.objects.all().order_by("pk")
serializer_class = serializers.SubraceSerializer
search_fields = ['name', 'desc']
Expand All @@ -333,13 +244,6 @@ class CharClassViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of classes and archetypes.
retrieve: API endpoint for returning a particular class or archetype.
"""
schema = CustomSchema(
summary={
'/classes/': 'List Classes',
'/classes/{slug}/': 'Retrieve Class',
},
tags=['Classes']
)
queryset = models.CharClass.objects.all().order_by("pk")
serializer_class = serializers.CharClassSerializer
filterset_class = filters.CharClassFilter
Expand All @@ -352,13 +256,6 @@ class ArchetypeViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint that allows viewing of Archetypes.
retrieve: API endpoint for returning a particular archetype.
"""
schema = CustomSchema(
summary={
'/archetypes/': 'List Archetypes',
'/archetypes/{slug}/': 'Retrieve Archetype',
},
tags=['Archetypes']
)
queryset = models.Archetype.objects.all().order_by("pk")
serializer_class = serializers.ArchetypeSerializer
search_fields = ['name', 'desc']
Expand All @@ -373,13 +270,6 @@ class MagicItemViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of magic items.
retrieve: API endpoint for returning a particular magic item.
"""
schema = CustomSchema(
summary={
'/magicitems/': 'List Magic Items',
'/magicitems/{slug}/': 'Retrieve Magic Item',
},
tags=['Magic Items']
)
queryset = models.MagicItem.objects.all().order_by("pk")
serializer_class = serializers.MagicItemSerializer
filterset_class = filters.MagicItemFilter
Expand All @@ -391,13 +281,6 @@ class WeaponViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of weapons.
retrieve: API endpoint for returning a particular weapon.
"""
schema = CustomSchema(
summary={
'/weapons/': 'List Weapons',
'/weapons/{slug}/': 'Retrieve Weapon',
},
tags=['Weapons']
)
queryset = models.Weapon.objects.all().order_by("pk")
serializer_class = serializers.WeaponSerializer
filterset_class = filters.WeaponFilter
Expand All @@ -409,13 +292,6 @@ class ArmorViewSet(viewsets.ReadOnlyModelViewSet):
list: API endpoint for returning a list of armor.
retrieve: API endpoint for returning a particular armor.
"""
schema = CustomSchema(
summary={
'/armor/': 'List Armor',
'/armor/{slug}/': 'Retrieve Armor',
},
tags=['Armor']
)
queryset = models.Armor.objects.all().order_by("pk")
serializer_class = serializers.ArmorSerializer
filterset_class = filters.ArmorFilter
Expand Down
10 changes: 10 additions & 0 deletions api_v2/models/armor.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ class Armor(HasName, FromDocument):
null=True,
help_text='Integer representing the dexterity modifier cap.')

@property
def category(self):
category = 'heavy'
if self.ac_add_dexmod:
category= 'light'
if self.ac_cap_dexmod:
category= 'medium'
return category


@property
def ac_display(self):
"""Display text for armor class."""
Expand Down
Loading
Loading