How should setup code be handled in entity-component-system?
My question is whether this object should be created in the component, which sort of violates the rule that entities should be pure data, or in the system. If it should best be done in a system, it would only need to be done once (and it would harm performance if the audio file needed to be created once per frame). What is the best way to do this?

When you use the outboard model for an entity system, I think one of the most important tasks to nail down is both entity and component life-cycle management.  Without it, it becomes really difficult to write system code that doesn't start to resemble spaghetti.
There are implementations out there where they expect you to construct the entity, build its component list, then activate the entity.  Once the entity is activated, you can't add or remove components, but only change the component's attribute values.  In order to add/remove components, you deactivate the entity, make the changes, then reactivate it.
Lets assume we use this entity life-cycle process.
When the entity with the audio component is activated, the audio system is notified, reads the attributes from the audio component, and finally creates the audio framework's sound object.  It would then be the system's responsibility to maintain a bookkeeping map between the component and sound object.  This internal map is what the system would use each frame to perform its update.
When the entity with the audio component is deactivated, the audio system is notified, destroys the audio framework's sound object associated with the component in the internal bookkeeping map, then removes the entry from the internal map.
I am writing an ECS framework and also a game with it, in Python. In an ECS framework, components should contain only data. However, sometimes setup code is needed to create the data. For example, in an audio component, the data would be the volume of the the sound to play and the path to the audio file. But in the audio-playing library, there are objects to represent sounds, which have a sound.play() method, for example. My question is whether this object should be created in the component, which sort of violates the rule that entities should be pure data, or in the system. If it should best be done in a system, it would only need to be done once (and it would harm performance if the audio file needed to be created once per frame). What is the best way to do this?