coveralls: 
[![Coverage Status](https://coveralls.io/builds/32431916/badge)](https://coveralls.io/builds/32431916)

Coverage remained the same at 100.0% when pulling **6e4229e98317b32475caf0a5589a44078b13c2e6 on aileenpongnon:issue/350-create-module-item** into **d8c0022e020ae0cfdbebecdf4df431dfc3ebf86b on ucfopen:develop**.

diff --git a/canvasapi/module.py b/canvasapi/module.py
index f235acb..fe6b3b2 100644
--- a/canvasapi/module.py
+++ b/canvasapi/module.py
@@ -122,8 +122,12 @@ class Module(CanvasObject):
         :returns: The created module item.
         :rtype: :class:`canvasapi.module.ModuleItem`
         """
+
+        unrequired_types = ["ExternalUrl", "Page", "SubHeader"]
+
         if isinstance(module_item, dict) and "type" in module_item:
-            if "content_id" in module_item:
+            # content_id is not required for unrequired_types
+            if module_item["type"] in unrequired_types or "content_id" in module_item:
                 kwargs["module_item"] = module_item
             else:
                 raise RequiredFieldMissing(

create_module_item() requires content_id for type SubHeader
# Describe the bug

In `create_module_item()`, I get an error `RequiredFieldMissing: Dictionary with key 'content_id' is required.` when trying to create a module item of type `SubHeader`.

The Canvas API documentation says that `content_id` is "Required, except for 'ExternalUrl', 'Page', and 'SubHeader' types." [Modules API # Create a module item](https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.create)

I think that currently the Python API checks to see if `content_id` is present regardless of what type of `module_item` is created.

# To Reproduce

```python
from canvasapi import Canvas
API_URL = "your_api_url"
API_KEY = "your_api_key"
canvas = Canvas(API_URL, API_KEY)
course = canvas.get_course(a_course_id)
module = course.create_module({'name':'a_module_name'})

# produces error RequiredFieldMissing: Dictionary with key 'content_id' is required.
module_item = module.create_module_item({'title':'a_title','type':'SubHeader'})

# workaround, add blank content_id
module_item = module.create_module_item({'title':'a_title','type':'SubHeader','content_id':''})
```

# Expected behavior

A module item of type `SubHeader` should be created without specifying a `content_id`.

# Environment information

- Python version (`python --version`)
3.8.1
- CanvasAPI version (`pip show canvasapi`)
0.15.0
# Additional context
No additional context.
diff --git a/tests/test_module.py b/tests/test_module.py
index 9f434d1..010c057 100644
--- a/tests/test_module.py
+++ b/tests/test_module.py
@@ -86,8 +86,9 @@ class TestModule(unittest.TestCase):
         register_uris({"module": ["create_module_item"]}, m)
 
         module_item = self.module.create_module_item(
-            module_item={"type": "Page", "content_id": 1}
+            module_item={"type": "Assignment", "content_id": 1}
         )
+
         self.assertIsInstance(module_item, ModuleItem)
         self.assertTrue(hasattr(module_item, "course_id"))
         self.assertEqual(module_item.course_id, self.course.id)
@@ -98,7 +99,13 @@ class TestModule(unittest.TestCase):
 
     def test_create_module_item_fail2(self, m):
         with self.assertRaises(RequiredFieldMissing):
-            self.module.create_module_item(module_item={"type": "Page"})
+            self.module.create_module_item(module_item={"type": "Assignment"})
+
+    def test_create_module_item_unrequired_success(self, m):
+        register_uris({"module": ["create_module_item"]}, m)
+
+        module_item = self.module.create_module_item(module_item={"type": "SubHeader"})
+        self.assertIsInstance(module_item, ModuleItem)
 
     # __str__
     def test__str__(self, m):

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio requests_mock
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
-e git+https://github.com/ucfopen/canvasapi.git@f9dba3b1ac215c5a58ed8d07b5b9ae2b1d75a9a9#egg=canvasapi
certifi==2025.1.31
charset-normalizer==3.4.1
coverage==7.8.0
exceptiongroup==1.2.2
execnet==2.1.1
idna==3.10
iniconfig==2.1.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-xdist==3.6.1
pytz==2025.2
requests==2.32.3
requests-mock==1.12.1
tomli==2.2.1
typing_extensions==4.13.0
urllib3==2.3.0

name: canvasapi
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - idna==3.10
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - pytz==2025.2
      - requests==2.32.3
      - requests-mock==1.12.1
      - tomli==2.2.1
      - typing-extensions==4.13.0
      - urllib3==2.3.0
prefix: /opt/conda/envs/canvasapi

tests/test_module.py::TestModule::test_create_module_item_unrequired_success
tests/test_module.py::TestModule::test__str__ tests/test_module.py::TestModule::test_create_module_item tests/test_module.py::TestModule::test_create_module_item_fail1 tests/test_module.py::TestModule::test_create_module_item_fail2 tests/test_module.py::TestModule::test_delete_module tests/test_module.py::TestModule::test_edit_module tests/test_module.py::TestModule::test_get_module_item tests/test_module.py::TestModule::test_get_module_items tests/test_module.py::TestModule::test_relock tests/test_module.py::TestModuleItem::test__str__ tests/test_module.py::TestModuleItem::test_complete tests/test_module.py::TestModuleItem::test_delete tests/test_module.py::TestModuleItem::test_edit_module_item tests/test_module.py::TestModuleItem::test_uncomplete
canvasapi/module.py
canvasapi/module.py